<?php
/**
 * Created by PhpStorm.
 * User: 86151 - 姜伟
 * Date: 2021/12/3 17:21
 */

namespace AnchuPac\PwdSlg\CheckPassword\Libs;

use AnchuPac\PwdSlg\Common\Util\ResUtil;
use AnchuPac\PwdSlg\Common\Util\SingletonUtil;
use AnchuPac\PwdSlg\CheckPassword\Consts\CheckPasswordConst;

class CheckPasswordSlg
{

    use SingletonUtil;
    
    private $redis;
    
    public function __construct($redis)
    {
        $this->redis = $redis;
    }
    
    // 获取后台账号输入密码错误的redis的key
    private function getAdminerInputPasswordRecordRedisKey($mobile = '')
    {
        $key = CheckPasswordConst::INPUT_PASSWORD_RECORD_KEY;
        return sprintf($key, $mobile);
    }

    // 获取后台账号输入密码错误的redis的key
    private function getAdminerLongtimeActionRedisKey($adminId = 0)
    {
        $key = CheckPasswordConst::LONGTIME_ACTION_KEY;
        return sprintf($key, $adminId);
    }

    // 获取锁定后台账号的redis的key
    private function getLockAccountByUsernameRedisKey($username = 0)
    {
        $key = CheckPasswordConst::LOCK_ACCOUNT_BY_USERNAME_KEY;
        return sprintf($key, $username);
    }

    // 锁定账号
    private function lockAccount($username = '')
    {
        $lockAccountRedisKey = $this->getLockAccountByUsernameRedisKey($username);
        $lockTime = CheckPasswordConst::INPUT_PASSWORD_ERROR_LOCK_EXPIRE_TIME;
        $this->redis->set($lockAccountRedisKey, $username);
        $this->redis->expire($lockAccountRedisKey, $lockTime);
    }

    // 检测X分钟内连续输入密码错误次数是否达到峰值
    public function checkInputPasswordTimes($adminId = '', $username = '')
    {
        if (empty($adminId)) {
            return [];
        }
        $redisKey = $this->getAdminerInputPasswordRecordRedisKey($adminId);
        $errorTimes = (int)$this->redis->get($redisKey);
        $canTimes = CheckPasswordConst::INPUT_PASSWORD_ERROR_TIMES;
        if ($errorTimes >= $canTimes) { // 输入密码连续错5次
            $lockTime = CheckPasswordConst::INPUT_PASSWORD_ERROR_LOCK_EXPIRE_TIME;
            $this->redis->expire($redisKey, $lockTime);
            $minute = ceil($lockTime / 60);
            $this->lockAccount($username);
            $errMsg = "很抱歉，您输入密码错误次数已超 {$canTimes} 次，账号已锁定，请于 {$minute} 分钟后重试";
            return ResUtil::getInstance()->responseFail($errMsg);
        }
        $this->redis->INCR($redisKey);
        $this->redis->expire($redisKey, 86400);
        $remainTimes = ($canTimes - $errorTimes - 1);
        $remainTimes = $remainTimes < 0 ? 0 : $remainTimes;
        $data = [
            'all_times' => $canTimes,
            'error_times' => $errorTimes + 1,
            'remain_times' => $remainTimes
        ];
        return ResUtil::getInstance()->responseSuccess($data);
    }

    // 检测是否锁定了账号
    public function checkIsLockAccountByUsername($username = '')
    {
        if (empty($username)) {
            return [];
        }
        $lockAccountRedisKey = $this->getLockAccountByUsernameRedisKey($username);
        $value = $this->redis->get($lockAccountRedisKey);
        $lockTime = CheckPasswordConst::INPUT_PASSWORD_ERROR_LOCK_EXPIRE_TIME;
        $minute = ceil($lockTime / 60);
        if (!empty($value)) {
            $errMsg = "很抱歉，您的账号已被锁定，请于 {$minute} 分钟后重试";
            return ResUtil::getInstance()->responseFail($errMsg);
        }
    }

    // 后台用户操作更新用户长期操作的redis的key
//    public function syncAdminerActionRedisKey($adminId = 0)
//    {
//        if (empty($adminId)) {
//            return [];
//        }
//        $redisKey = $this->getAdminerLongtimeActionRedisKey($adminId);
//        $expireTime = CheckPasswordConst::ADMINER_LONGTIME_ACTION_EXPIRE_TIME;
//        $this->redis->set($redisKey, $adminId);
//        $this->redis->expire($redisKey, $expireTime);
//    }

    // 检查用户是否长时间未操作
//    public function checkAdminerIsLongtimeNotAction($adminId = 0)
//    {
//        if (empty($adminId)) {
//            return false;
//        }
//        $redisKey = $this->getAdminerLongtimeActionRedisKey($adminId);
//        $value = $this->redis->get($redisKey);
//        if (empty($value)) {
//            return true;
//        }
//        return false;
//    }

}